package de.uni.bremen.estudent.lbs.provider;

import java.io.IOException;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;
import de.uni.bremen.estudent.lbs.provider.EstudentLBSContract.Categories;
import de.uni.bremen.estudent.lbs.provider.EstudentLBSContract.Meals;
import de.uni.bremen.estudent.lbs.provider.EstudentLBSContract.Pois;
import de.uni.bremen.estudent.lbs.provider.EstudentLBSDatabase.Tables;

/**
 * ContentProvider for the estudenLBS app.
 *
 * @author bahlfeld
 * @version 1.0 31.01.2012
 */
public final class EstudentLBSProvider extends ContentProvider {

    private static final int CATEGORIES = 100;

    private static final int CATEGORIES_ID = 101;


    private static final int MEALS = 300;
    private static final int MEALS_ID = 301;
    private static final UriMatcher mUriMatcher = buildUriMatcher();
    private static final int POIS = 200;
    private static final int POIS_ID = 201;
    private static final int POIS_JOIN = 202;
    private static final String TAG = "estudentContentProvider";

    private EstudentLBSDatabase dbHelper;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = EstudentLBSContract.CONTENT_AUTHORITY;

        matcher.addURI(authority, "categories", CATEGORIES);
        matcher.addURI(authority, "categories/*", CATEGORIES_ID);
        matcher.addURI(authority, "pois", POIS);
        matcher.addURI(authority, "pois/*", POIS_ID);
        matcher.addURI(authority, "pois/join", POIS_JOIN);
        matcher.addURI(authority, "meals", MEALS);
        matcher.addURI(authority, "meals/*", MEALS_ID);

        return matcher;
    }

    @Override
    public int delete(final Uri uri, final String whereClause,
            final String[] whereArgs) {
        SQLiteDatabase db = this.dbHelper.getWritableDatabase();
        int count;
        switch (mUriMatcher.match(uri)) {
        case MEALS:
            count = db.delete(Tables.MEALS, whereClause, whereArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown uri" + uri);
        }
        this.getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public String getType(final Uri uri) {
        switch (mUriMatcher.match(uri)) {
        case CATEGORIES:
            return Categories.CONTENT_TYPE;
        case CATEGORIES_ID:
            return Categories.CONTENT_ITEM_TYPE;
        case POIS:
            return Pois.CONTENT_TYPE;
        case POIS_ID:
            return Pois.CONTENT_ITEM_TYPE;

        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }

    @Override
    public Uri insert(final Uri uri, final ContentValues values) {
        SQLiteDatabase db = this.dbHelper.getWritableDatabase();
        switch (mUriMatcher.match(uri)) {
        case MEALS:
            long rowId = db.insert(Tables.MEALS, null, values);
            if (rowId > 0) {
                Uri mealUri = ContentUris.withAppendedId(Meals.CONTENT_URI,
                        rowId);
                this.getContext().getContentResolver()
                        .notifyChange(mealUri, null);
                return mealUri;
            }
            break;
        }
        throw new SQLiteException("Failed to insert row into " + uri);
    }

    /*
     * (non-Javadoc)
     *
     * @see android.content.ContentProvider#onCreate()
     */
    @Override
    public boolean onCreate() {
        if (this.dbHelper != null) {
            this.dbHelper.close();
        }
        this.dbHelper = new EstudentLBSDatabase(this.getContext());
        try {
            this.dbHelper.createDataBase();
            return true;
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        final SQLiteDatabase db = this.dbHelper.getReadableDatabase();
        final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        switch (mUriMatcher.match(uri)) {
        case CATEGORIES:
            builder.setTables(Tables.CATEGORIES);
            break;
        case POIS:
            builder.setTables(" pois p JOIN categories c ON p.category=c._id");
            return db
                    .rawQuery(
                            "SELECT * FROM pois LEFT JOIN categories ON pois.category = categories._id",
                            new String[] {});
            // return builder.query(db,new String[] {"p._id", "p.name", "p.lat",
            // "p.lon","c.name as category_name","c.icon", "c.description"},
            // selection, selectionArgs, null, null, null);
            // builder.setTables(Tables.POIS);

        case POIS_JOIN:
            break;
        case MEALS:
            builder.setTables(Tables.MEALS);
        }
        return builder.query(db, projection, selection, selectionArgs, null,
                null, null);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}
